package com.qax.task.timer;

import com.qax.task.cron.support.CronSequenceGenerator;
import com.qax.task.logger.Logger;
import com.qax.task.logger.LoggerFactory;
import lombok.Builder;
import lombok.Data;

import java.lang.reflect.Field;
import java.util.Date;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

/**
 * @author lianglei
 * <BR>此类用于测试时间轮调度算法<BR/>
 */
public class TimeWheelCase {
    private static final Logger LOGGER = LoggerFactory.getLogger(TimeWheelCase.class);

    private static CountDownLatch task1CountDownLatch = new CountDownLatch(1);
    private static CountDownLatch task2CountDownLatch = new CountDownLatch(1);
    private static CountDownLatch task3CountDownLatch = new CountDownLatch(1);
    private static CountDownLatch task4CountDownLatch = new CountDownLatch(1);

    @Data
    @Builder
    private static class DelayTestTask1 implements TimerTask {
        String context;

        @Override
        public void run(Timeout timeout) throws Exception {
            LOGGER.info("TimeWheelCase DelayTestTask1 run ...");
            //timeout.timer().newTimeout(this,0,TimeUnit.SECONDS);
            Field task = timeout.task().getClass().getDeclaredField("context");
            LOGGER.info("task:" + task.get(this));
        }
    }

    private static class TestTask2 implements TimerTask {
        @Override
        public void run(Timeout timeout) {
            LOGGER.info("TimeWheelCase TestTask2 run ...");
            task2CountDownLatch.countDown();
        }
    }


    private static class ImmediatelyTask implements TimerTask {
        @Override
        public void run(Timeout timeout) {
            LOGGER.info("TimeWheelCase ImmediatelyTask run ...");
            task3CountDownLatch.countDown();
        }
    }


    private static class CronTask implements TimerTask {
        @Override
        public void run(Timeout timeout) {
            LOGGER.info("TimeWheelCase CronTask run ...");
            task3CountDownLatch.countDown();
        }
    }


    public static void main(String[] args) throws InterruptedException {
        Timer timer = new HashedWheelTimer(new NamedThreadFactory("future-timeout", true));
        // 1 todo 延迟任务执行
        timer.newTimeout(DelayTestTask1.builder().context("qqq").build(), 5, TimeUnit.SECONDS);
        task1CountDownLatch.await();
        timer.newTimeout(new TestTask2(), 5, TimeUnit.SECONDS);
        task2CountDownLatch.await();

        // 2 todo 立即执行
        Timeout immediatelyTaskTimer = timer.newTimeout(new ImmediatelyTask(), 0, TimeUnit.SECONDS);
        task3CountDownLatch.await();


//        //3 todo 固定时间点执行，或者周期执行，下个月第二个星期二上午八点
//        String cron="0 0/10 * * * ? ";
//        CronSequenceGenerator cronSequenceGenerator = new CronSequenceGenerator(cron);
//        Date next = cronSequenceGenerator.next(new Date());
//        Timeout timeout = timer.newTimeout(new CronTask(),next.getTime(), TimeUnit.SECONDS);
//        task4CountDownLatch.await();


        // 4 todo 周期区间任务
        String crons = "0 0/10 * * * ? ";
        CronSequenceGenerator cronSequenceGenerators = new CronSequenceGenerator(crons);
        Date nexts = cronSequenceGenerators.next(new Date());
        Timeout timeouts = timer.newTimeout(new CronTask(), nexts.getTime(), TimeUnit.SECONDS);

        /**
         * @see com.qax.task.timer.Timeout
         * <pre>
         *         timeouts.cancel();
         * <pre/>
         */

        timeouts.cancel(); //把任务从当前任务组种去掉，即可实现周期性区间任务的流程
    }
}